package com.ganmiao.server.user.service;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.ganmiao.constant.AuthConstants;
import com.ganmiao.exception.DefaultBusinessException;
import com.ganmiao.resp.CommonResultRes;
import com.ganmiao.resp.MobBaseRes;
import com.ganmiao.resp.ResponseCode;
import com.ganmiao.server.supplier.entity.SupplierUser;
import com.ganmiao.server.supplier.service.SupplierUserService;
import com.ganmiao.server.sys.dto.RetrievePasswordDto;
import com.ganmiao.server.sys.entity.SysUser;
import com.ganmiao.server.sys.entity.SysUserAccount;
import com.ganmiao.server.sys.repository.SysUserAccountRepository;
import com.ganmiao.server.sys.repository.SysUserRepository;
import com.ganmiao.server.sys.service.SysMenuService;
import com.ganmiao.server.sys.service.SysRoleService;
import com.ganmiao.server.sys.service.SysUserService;
import com.ganmiao.server.sys.vo.SysMenuVo;
import com.ganmiao.server.sys.vo.SysRoleVo;
import com.ganmiao.server.sys.vo.SysUserVo;
import com.ganmiao.server.user.context.UserAuthContext;
import com.ganmiao.server.user.dto.ShopUserLoginDto;
import com.ganmiao.server.user.dto.WxLoginReq;
import com.ganmiao.server.user.vo.MallUserVo;
import com.ganmiao.server.user.dto.LoginReq;
import com.ganmiao.server.user.dto.WxPhoneLoginReq;
import com.ganmiao.server.user.enums.SysCodeEnum;
import com.ganmiao.server.user.vo.SMSCodeResponseVo;
import com.ganmiao.server.user.vo.SMSCodeVo;
import com.ganmiao.server.user.vo.UserLonginVo;
import com.ganmiao.utils.HttpUtil;
import com.ganmiao.utils.JwtUtils;
import com.ganmiao.utils.RedisUtil;
import com.ganmiao.utils.StatusUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * 用户登录
 */
@Service
@Slf4j
public class UserLoginService {

    //用户账号信息
    @Autowired
    private SysUserAccountRepository sysUserAccountRepository;

    //用户信息
    @Autowired
    private SysUserService sysUserService;

    //角色信息
    @Autowired
    private SysRoleService sysRoleService;

    //菜单信息
    @Autowired
    private SysMenuService sysMenuService;

    //redis
    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private SupplierUserService supplierUserService;

//    @Autowired
//    private ShopInfoService shopInfoService;
//
//    @Autowired
//    private MallUserService mallUserService;
//
//    @Autowired
//    private ShopUserService shopUserService;

    @Autowired
    private SysUserRepository sysUserRepository;

    /**
     * 管理后台用户登录
     *
     * @param sysUserAccount
     * @return
     */
    public UserLonginVo userLogin(SysUserAccount sysUserAccount) {
        //查询条件
        LambdaQueryWrapper<SysUserAccount> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysUserAccount::getUserAccount, sysUserAccount.getUserAccount())
                .eq(SysUserAccount::getUserPassword, DigestUtil.md5Hex(sysUserAccount.getUserPassword()))
                .eq(SysUserAccount::getSysCode, sysUserAccount.getSysCode())
                .eq(SysUserAccount::getStatus, StatusUtils.PASS);
        //查询结果
        SysUserAccount userAccount = sysUserAccountRepository.getOne(queryWrapper);
        //账号或密码错误
        if (ObjectUtil.isNull(userAccount)) {
            throw new DefaultBusinessException("账号或密码错误！");
        }
        //账号审核中
        if ("0".equals(userAccount.getStatus())) {
            throw new DefaultBusinessException("账号审核中！");
        }
        //账号已停用
        if ("3".equals(userAccount.getStatus())) {
            throw new DefaultBusinessException("账号已停用，请联系管理员！");
        }

        // 登录成功，生成jwt
        String jwtToken = JwtUtils.getJwtToken(userAccount.getAccountId());
        //token存入redis
        redisUtil.set(AuthConstants.USER_TOKEN, jwtToken, AuthConstants.EXP_TOKEN_MILLSECOND);
        //获取用户信息
        SysUserVo sysUserById = sysUserService.getSysUserById(userAccount.getUserId());

        //供应商登录
        if (sysUserAccount.getSysCode().equals(SysCodeEnum.SUPPLIER.getCode())) {
            SupplierUser supplierUser = supplierUserService.getSupplierId(sysUserById.getUserId());
            sysUserById.setSupplierId(supplierUser.getSupplierId());
        }

//        //商超登录
//        if (sysUserAccount.getSysCode().equals(SysCodeEnum.SUPERMARKET.getCode())) {
//            ShopUser shopUser = shopInfoService.getShopId(sysUserById.getUserId());
//            sysUserById.setShopId(shopUser.getShopId());
//        }

        //获取角色信息
        List<SysRoleVo> sysRoleVoList = new ArrayList<>();
        if (!sysUserById.getRoleIds().isEmpty()) {
            sysRoleVoList = sysRoleService.getSysRoleIds(sysUserById.getRoleIds());
        }

        //获取菜单信息
        List<SysMenuVo> sysMenuByIds = new ArrayList<>();
        if (!sysRoleVoList.isEmpty()) {
            if (StringUtils.isBlank(sysUserAccount.getMenuList()) || "0".equals(sysUserAccount.getMenuList())) {
                sysMenuByIds = sysMenuService.getSysMenuByIds(sysRoleVoList.get(0).getMenuIds());
            } else {
                sysMenuByIds = sysMenuService.getSysMenuByIds(sysRoleVoList.get(0).getH5MenuIds());
            }
        }

        //登录用户信息和系统编码放入私有线程
        UserAuthContext.init();
        UserAuthContext.setSysCode(userAccount.getSysCode());
        UserAuthContext.setLoginUser(sysUserById);

        //登录用户信息
        UserLonginVo userLonginVo = UserLonginVo.builder()
                .token(jwtToken)
                .loginUser(sysUserById)
                .sysRoleVo(!sysRoleVoList.isEmpty() ? sysRoleVoList.get(0) : null)
                .sysRoleVoList(sysRoleVoList)
                .sysMenuVoList(sysMenuByIds)
                .build();

        //登录用户信息存入redis
        redisUtil.set(AuthConstants.USER_LOGIN + ":" + jwtToken, JSON.toJSONString(userLonginVo), AuthConstants.EXP_TOKEN_MILLSECOND);

        return userLonginVo;
    }

    public SMSCodeVo SMSCode(String mobile) {
        String apiKey = "f983cef477245bb7d16d15d5ac9f7269";
        String textFront = "【校园云采】您的验证码是";
        String textAfter = "。如非本人操作，请忽略本短信";
        String url = "https://sms.yunpian.com/v2/sms/single_send.json";
        Random random = new Random();
        String code = "";
        for (int i = 0; i < 6; i++) {
            //获取5位验证码
            int randomNum = random.nextInt(10);
            code += randomNum;
        }
        String text = textFront + code + textAfter;
        HashMap<String, String> headers = new HashMap<>();
        headers.put("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
        HashMap<String, Object> params = new HashMap<>();
        params.put("apikey", apiKey);
        params.put("mobile", mobile);
        params.put("text", text);
        String response = HttpUtil.doPost(url, params, headers);
        SMSCodeResponseVo responseVo = JSONObject.parseObject(response, SMSCodeResponseVo.class);
        //redis调用存验证码
        if (responseVo.getCode() == 0) {
            redisUtil.set(mobile, code, 180);
            SMSCodeVo vo = new SMSCodeVo();
            BeanUtils.copyProperties(responseVo, vo);
            return vo;
        } else {
            throw new DefaultBusinessException(responseVo.getMsg(), ResponseCode.FAIL);
        }
    }

    public SMSCodeVo CheckSMSCode(String mobile, String SMSCode) {
        if (redisUtil.hasKey(mobile)) {
            if (redisUtil.get(mobile).equals(SMSCode)) {
                SMSCodeVo vo = new SMSCodeVo();
                vo.setCode(0);
                vo.setMobile(mobile);
                vo.setMsg("验证成功");
                return vo;
            } else {
                throw new DefaultBusinessException("验证码不正确", ResponseCode.FAIL);
            }
        } else {
            throw new DefaultBusinessException("验证码已失效", ResponseCode.FAIL);
        }
    }

    //商城微信登录
//    public UserLonginVo mallWeixinLogin(WxLoginReq req) {
//        MallUserVo mallUserVo ;
//        if (req.getUserId() == null) {
//            mallUserVo = mallUserService.weixinLogin(req);
//        } else {
//            mallUserVo = mallUserService.weixinLogin2(req);
//        }
//
//        // 登录成功，生成jwt
//        String jwtToken = JwtUtils.getJwtTokenV2("mall_" + mallUserVo.getUserId());
//        //token存入redis
//        redisUtil.set(AuthConstants.USER_TOKEN, jwtToken, AuthConstants.EXP_TOKEN_MILLSECOND);
//
//        //登录用户信息和系统编码放入私有线程
//        UserAuthContext.init();
//        UserAuthContext.setMallUser(mallUserVo);
//
//        //登录用户信息
//        UserLonginVo userLonginVo = UserLonginVo.builder()
//                .token(jwtToken)
//                .mallUser(mallUserVo)
//                .build();
//        redisUtil.set(AuthConstants.USER_LOGIN + ":" + jwtToken, JSON.toJSONString(userLonginVo), AuthConstants.EXP_TOKEN_MILLSECOND);
//
//        return userLonginVo;
//    }
//
//    //商城微信手机号授权登录
//    public UserLonginVo mallWeixinPhoneLogin(WxPhoneLoginReq req) {
//        MallUserVo mallUserVo = mallUserService.weixinPhoneLogin(req);
//
//        // 登录成功，生成jwt
//        String jwtToken = JwtUtils.getJwtTokenV2("mall_" + mallUserVo.getUserId());
//        //token存入redis
//        redisUtil.set(AuthConstants.USER_TOKEN, jwtToken, AuthConstants.EXP_TOKEN_MILLSECOND);
//
//        //登录用户信息和系统编码放入私有线程
//        UserAuthContext.init();
//        UserAuthContext.setMallUser(mallUserVo);
//
//        //登录用户信息
//        UserLonginVo userLonginVo = UserLonginVo.builder()
//                .token(jwtToken)
//                .mallUser(mallUserVo)
//                .build();
//        redisUtil.set(AuthConstants.USER_LOGIN + ":" + jwtToken, JSON.toJSONString(userLonginVo), AuthConstants.EXP_TOKEN_MILLSECOND);
//
//        return userLonginVo;
//    }

//    //商城账号密码登录
//    public UserLonginVo mallAccountLogin(LoginReq loginReq) {
//        MallUserVo mallUserVo = mallUserService.accountLogin(loginReq);
//
//        // 登录成功，生成jwt
//        String jwtToken = JwtUtils.getJwtTokenV2("mall_" + mallUserVo.getUserId());
//        //token存入redis
//        redisUtil.set(AuthConstants.USER_TOKEN, jwtToken, AuthConstants.EXP_TOKEN_MILLSECOND);
//
//        //登录用户信息和系统编码放入私有线程
//        UserAuthContext.init();
//        UserAuthContext.setMallUser(mallUserVo);
//
//        //登录用户信息
//        UserLonginVo userLonginVo = UserLonginVo.builder()
//                .token(jwtToken)
//                .mallUser(mallUserVo)
//                .build();
//        redisUtil.set(AuthConstants.USER_LOGIN + ":" + jwtToken, JSON.toJSONString(userLonginVo), AuthConstants.EXP_TOKEN_MILLSECOND);
//
//        return userLonginVo;
//    }

    /**
     * 商超用户登录
     *
     * @param param
     * @return
     */
//    public UserLonginVo shopUserLogin(ShopUserLoginDto param) {
//        //查询条件
//        LambdaQueryWrapper<SysUserAccount> queryWrapper = new LambdaQueryWrapper<>();
//        queryWrapper.eq(SysUserAccount::getUserAccount, param.getAccount())
//                .eq(SysUserAccount::getUserPassword, DigestUtil.md5Hex(param.getPassword()))
//                .eq(SysUserAccount::getSysCode, SysCodeEnum.SUPERMARKET)
//                .ne(SysUserAccount::getStatus, StatusUtils.FAILURE);
//        //查询结果
//        SysUserAccount userAccount = sysUserAccountRepository.getOne(queryWrapper);
//        //账号或密码错误
//        if (ObjectUtil.isNull(userAccount)) {
//            throw new DefaultBusinessException("账号或密码错误！");
//        }
//        //账号审核中
//        if ("0".equals(userAccount.getStatus())) {
//            throw new DefaultBusinessException("账号审核中！");
//        }
//        //账号已停用
//        if ("3".equals(userAccount.getStatus())) {
//            throw new DefaultBusinessException("账号已停用，请联系管理员！");
//        }
//
//        // 登录成功，生成jwt
//        String jwtToken = JwtUtils.getJwtToken(userAccount.getAccountId());
//        //token存入redis
//        redisUtil.set(AuthConstants.USER_TOKEN, jwtToken, AuthConstants.EXP_TOKEN_MILLSECOND);
//        //获取用户信息
//        SysUserVo sysUserById = sysUserService.getSysUserById(userAccount.getUserId());
//
//        //获取角色信息
//        List<SysRoleVo> sysRoleVoList = new ArrayList<>();
//        if (!sysUserById.getRoleIds().isEmpty()) {
//            sysRoleVoList = sysRoleService.getSysRoleIds(sysUserById.getRoleIds());
//        }
//
//        //获取菜单信息
//        List<SysMenuVo> sysMenuByIds = new ArrayList<>();
//        if (!sysRoleVoList.isEmpty()) {
//            if (StringUtils.isBlank(param.getMenuList()) || "0".equals(param.getMenuList())) {
//                sysMenuByIds = sysMenuService.getSysMenuByIds(sysRoleVoList.get(0).getMenuIds());
//            } else {
//                sysMenuByIds = sysMenuService.getSysMenuByIds(sysRoleVoList.get(0).getH5MenuIds());
//            }
//        }
//
//        List<Integer> shopIds = shopUserService.getShopIds(userAccount.getUserId());
//        if (shopIds.isEmpty()) {
//            throw new DefaultBusinessException("暂未绑定商超");
//        }
//        List<ShopInfoVo> shopInfoList = shopInfoService.getShopInfoList(shopIds);
//
//        //登录用户信息和系统编码放入私有线程
//        UserAuthContext.init();
//        UserAuthContext.setSysCode(userAccount.getSysCode());
//        UserAuthContext.setLoginUser(sysUserById);
//
//        //登录用户信息
//        UserLonginVo userLonginVo = UserLonginVo.builder()
//                .token(jwtToken)
//                .loginUser(sysUserById)
//                .sysRoleVo(!sysRoleVoList.isEmpty() ? sysRoleVoList.get(0) : null)
//                .sysRoleVoList(sysRoleVoList)
//                .sysMenuVoList(sysMenuByIds)
//                .shopInfoVoList(shopInfoList)
//                .build();
//
//        //登录用户信息存入redis
//        redisUtil.set(AuthConstants.USER_LOGIN + ":" + jwtToken, JSON.toJSONString(userLonginVo), AuthConstants.EXP_TOKEN_MILLSECOND);
//
//        return userLonginVo;
//    }

    /**
     * 选择商超
     *
     * @param shopId
     * @return
     */
    public CommonResultRes<UserLonginVo> choice(Integer shopId, HttpServletRequest request) {
        //校验登录
        String token = request.getHeader("token");
        if (StringUtils.isEmpty(token)) {
            throw new DefaultBusinessException(ResponseCode.TOKEN_EXPIRED_EXCEPTION);
        }
        // ① redis取登录用户信息
        String loginInfoStr = redisUtil.get(AuthConstants.USER_LOGIN + ":" + token);
        if (Objects.isNull(loginInfoStr)) {
            throw new DefaultBusinessException(ResponseCode.TOKEN_EXPIRED_EXCEPTION);
        }
        UserLonginVo userLonginVo = com.alibaba.fastjson.JSON.parseObject(loginInfoStr, UserLonginVo.class);
        SysUserVo loginUser = userLonginVo.getLoginUser();
        loginUser.setShopId(shopId);
        redisUtil.set(AuthConstants.USER_LOGIN + ":" + token, JSON.toJSONString(userLonginVo), AuthConstants.EXP_TOKEN_MILLSECOND);
        UserAuthContext.init();
        if (Objects.nonNull(loginUser)) {
            UserAuthContext.setLoginUser(loginUser);
            //系统编码放入私有线程
            UserAuthContext.setSysCode(loginUser.getSysCode());
        }
        return new CommonResultRes<>(userLonginVo);
    }

    /**
     * 供应商后台用户登录
     *
     * @param sysUserAccount
     * @return
     */
    public UserLonginVo supplierLogin(SysUserAccount sysUserAccount) {
        //查询条件
        LambdaQueryWrapper<SysUserAccount> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysUserAccount::getUserAccount, sysUserAccount.getUserAccount())
                .eq(SysUserAccount::getUserPassword, DigestUtil.md5Hex(sysUserAccount.getUserPassword()))
                .eq(SysUserAccount::getSysCode, sysUserAccount.getSysCode())
                .eq(SysUserAccount::getStatus, StatusUtils.PASS);
        //查询结果
        SysUserAccount userAccount = sysUserAccountRepository.getOne(queryWrapper);
        //账号或密码错误
        if (ObjectUtil.isNull(userAccount)) {
            throw new DefaultBusinessException("账号或密码错误！");
        }
        //账号审核中
        if ("0".equals(userAccount.getStatus())) {
            throw new DefaultBusinessException("账号审核中！");
        }
        //账号已停用
        if ("3".equals(userAccount.getStatus())) {
            throw new DefaultBusinessException("账号已停用，请联系管理员！");
        }

        // 登录成功，生成jwt
        String jwtToken = JwtUtils.getJwtToken(userAccount.getAccountId());
        //token存入redis
        redisUtil.set(AuthConstants.USER_TOKEN, jwtToken, AuthConstants.EXP_TOKEN_MILLSECOND);
        //获取用户信息
        SysUserVo sysUserById = sysUserService.getSysUserById(userAccount.getUserId());

        //供应商登录
        if (sysUserAccount.getSysCode().equals(SysCodeEnum.SUPPLIER.getCode())) {
            SupplierUser supplierUser = supplierUserService.getSupplierId(sysUserById.getUserId());
            sysUserById.setSupplierId(supplierUser.getSupplierId());
        }

        //获取角色信息
        List<SysRoleVo> sysRoleVoList = new ArrayList<>();
        if (!sysUserById.getRoleIds().isEmpty()) {
            sysRoleVoList = sysRoleService.getSysRoleIds(sysUserById.getRoleIds());
        }

        //获取菜单信息
        List<SysMenuVo> sysMenuByIds = new ArrayList<>();
        if (!sysRoleVoList.isEmpty()) {
            if (StringUtils.isBlank(sysUserAccount.getMenuList()) || "0".equals(sysUserAccount.getMenuList())) {
                sysMenuByIds = sysMenuService.getSysMenuByIds(sysRoleVoList.get(0).getMenuIds());
            } else {
                sysMenuByIds = sysMenuService.getSysMenuByIds(sysRoleVoList.get(0).getH5MenuIds());
            }
        }

        //登录用户信息和系统编码放入私有线程
        UserAuthContext.init();
        UserAuthContext.setSysCode(userAccount.getSysCode());
        UserAuthContext.setLoginUser(sysUserById);

        //登录用户信息
        UserLonginVo userLonginVo = UserLonginVo.builder()
                .token(jwtToken)
                .loginUser(sysUserById)
                .sysRoleVo(!sysRoleVoList.isEmpty() ? sysRoleVoList.get(0) : null)
                .sysRoleVoList(sysRoleVoList)
                .sysMenuVoList(sysMenuByIds)
                .build();

        //登录用户信息存入redis
        redisUtil.set(AuthConstants.USER_LOGIN + ":" + jwtToken, JSON.toJSONString(userLonginVo), AuthConstants.EXP_TOKEN_MILLSECOND);

        return userLonginVo;
    }

    public MobBaseRes retrievePassword(RetrievePasswordDto retrievePasswordDto) {
        if (StringUtils.isBlank(retrievePasswordDto.getTelphone())) {
            return new MobBaseRes(ResponseCode.FAIL.getCode(), "手机号不能为空");
        }
        if (StringUtils.isBlank(retrievePasswordDto.getPassword())) {
            return new MobBaseRes(ResponseCode.FAIL.getCode(), "密码不能为空");
        }
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysUser::getUserPhone, retrievePasswordDto.getTelphone());
        queryWrapper.eq(SysUser::getStatus, StatusUtils.PASS);
        queryWrapper.eq(SysUser::getSysCode, "portal");
        List<SysUser> sysUserList = sysUserRepository.list(queryWrapper);
        if (sysUserList.isEmpty()) {
            return new MobBaseRes(ResponseCode.FAIL.getCode(), "账号不存在");
        }
        LambdaQueryWrapper<SysUserAccount> sysUserAccountLambdaQueryWrapper = new LambdaQueryWrapper<>();
        sysUserAccountLambdaQueryWrapper.eq(SysUserAccount::getUserId, sysUserList.get(0).getUserId());
        sysUserAccountLambdaQueryWrapper.eq(SysUserAccount::getStatus, StatusUtils.PASS);
        SysUserAccount sysUserAccount = sysUserAccountRepository.getOne(sysUserAccountLambdaQueryWrapper);
        if (sysUserAccount == null) {
            return new MobBaseRes(ResponseCode.FAIL.getCode(), "账号不存在");
        }
        sysUserAccount.setUserPassword(DigestUtil.md5Hex(retrievePasswordDto.getPassword()));
        return sysUserAccountRepository.updateById(sysUserAccount) ?
                new MobBaseRes(ResponseCode.SUCCESS.getCode(), "修改成功") :
                new MobBaseRes(ResponseCode.FAIL.getCode(), "修改失败");

    }
}
